home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / v10n12.arc / DEV.C < prev    next >
Text File  |  1991-05-30  |  6KB  |  208 lines

  1. /* 
  2. DEV.C -- display MS-DOS device chain
  3.  
  4. Copyright (c) 1991 Ziff Communications Co.
  5.     PC Magazine * Andrew Schulman
  6.         
  7. real mode:
  8.     Borland C++ 2.0: bcc dev.c
  9.     Microsoft C 6.0: cl dev.c
  10.  
  11. Borland C++ 2.0 (DPMI.C *must* be compiled with -B flag):
  12.     bcc -W -DWINDOWS -2 -B dev.c printf.c dpmi.c 
  13.     rc dev.exe
  14.         
  15. Microsoft C 6.0:        
  16.     cl -c -AS -G2sw -Oais -Zpe -W3 -DWINDOWS dev.c printf.c dpmi.c
  17.     link /align:16 dev dpmi printf,dev,,/nod slibcew libw,win.def
  18.     rc dev.exe
  19.         
  20. WIN.DEF:
  21.     ; WIN.DEF -- generic Windows .DEF file
  22.     EXETYPE         WINDOWS
  23.     STUB            'WINSTUB.EXE'
  24.     CODE            PRELOAD MOVEABLE DISCARDABLE
  25.     DATA            PRELOAD MOVEABLE MULTIPLE
  26.     HEAPSIZE        10240
  27.     STACKSIZE       5120
  28. */
  29.  
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <dos.h>
  34. #ifdef WINDOWS
  35. #include <windows.h>
  36. #include "dpmi.h"
  37. #include "printf.h"
  38. #endif
  39.  
  40. #ifdef WINDOWS
  41. char *app = "Walk DOS Device Chain";
  42. #define puts(s)   MessageBox(NULL, s, app, MB_OK)
  43. #endif
  44. #define fail(s)   return puts(s)
  45.  
  46. #ifndef MK_FP
  47. #define MK_FP(seg, ofs) \
  48.     ((void far *) (((unsigned long) (seg) << 16) | (ofs)))
  49. #endif      
  50.  
  51. /* some device attribute bits */
  52. #define CHAR_DEV    (1 << 15)
  53. #define INT29       (1 << 4)
  54. #define IS_CLOCK    (1 << 3)
  55. #define IS_NUL      (1 << 2)
  56.  
  57. #pragma pack(1)
  58.  
  59. typedef struct DeviceDriver {
  60.     struct DeviceDriver far *next;
  61.     unsigned attr;
  62.     unsigned strategy;
  63.     unsigned intr;
  64.     union {
  65.         unsigned char name[8];
  66.         unsigned char blk_cnt;
  67.         } u;
  68.     } DeviceDriver;
  69.  
  70. typedef struct {
  71.     unsigned char misc[8];
  72.     DeviceDriver far *clock;
  73.     DeviceDriver far *con;
  74.     unsigned char misc2[18];
  75.     DeviceDriver nul;   /* not a pointer */
  76.     // ...
  77.     
  78.     } ListOfLists;  // DOS 3.1+
  79.         
  80. ListOfLists far *get_doslist(void)
  81. {
  82. #ifdef WINDOWS  
  83.     /*
  84.         Call undocumented DOS INT 21h Function 52h via DPMI "Simulate
  85.         Real Mode Interrupt" call (INT 31h AX=0300h), and return
  86.         the resulting real-mode pointer
  87.     */
  88.     RMODE_CALL r;
  89.     memset(&r, 0, sizeof(r));
  90.     r.eax = 0x5200;
  91.     return (dpmi_rmode_intr(0x21, 0, 0, &r)) ? MK_FP(r.es, r.ebx) : 0;
  92. #else   
  93.     union REGS r;
  94.     struct SREGS s;
  95.     segread(&s);
  96.     s.es = r.x.bx = 0;
  97.     r.h.ah = 0x52;
  98.     intdosx(&r, &r, &s);
  99.     return MK_FP(s.es, r.x.bx);
  100. #endif
  101. }
  102.  
  103. #ifdef WINDOWS
  104. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
  105.     LPSTR lpszCmdLine, int nCmdShow)
  106. #else       
  107. int main(int argc, char *argv[])
  108. #endif
  109. {
  110.     ListOfLists far *doslist;
  111.     DeviceDriver far *dd;
  112. #ifdef WINDOWS
  113.     DeviceDriver far *next;
  114.     int mapped;
  115. #endif
  116.     
  117. #ifdef WINDOWS
  118.     if (! (GetWinFlags() & WF_PMODE))
  119.         fail("This program requires Windows Standard or Enhanced mode");
  120.  
  121.     if (! dpmi_present())
  122.         fail("This program requires DPMI INT 31h services");
  123. #endif  
  124.  
  125.     if (! (doslist = get_doslist()))
  126.         fail("INT 21h Function 52h not supported");
  127.     
  128. #ifdef WINDOWS  
  129.     /* get protected-mode pointer to DOS internal variable table */
  130.     doslist = map_real(doslist, sizeof(ListOfLists));
  131.  
  132.     open_display(app);
  133. #endif  
  134.  
  135.     /* This block of code double-checks that everything is ok */
  136.     /* NUL is part of DOSLIST, not a pointer, so don't need to map */
  137.     if (_fmemcmp(doslist->nul.u.name, "NUL     ", 8) != 0)
  138.         fail("NUL name wrong");
  139.     if (! (doslist->nul.attr & IS_NUL))
  140.         fail("NUL attr wrong");
  141.     
  142. #ifdef WINDOWS
  143.     /* CON is pointer, so need to map */
  144.     dd = map_real(doslist->con, sizeof(DeviceDriver));
  145. #else
  146.     dd = doslist->con;
  147. #endif
  148.     if (_fmemcmp(dd->u.name, "CON     ", 8) != 0)
  149.         fail("CON name wrong");
  150.     if (! (dd->attr & CHAR_DEV))
  151.         fail("CON attr wrong");
  152. #ifdef WINDOWS
  153.     free_mapped_seg(dd);
  154. #endif
  155.     
  156. #ifdef WINDOWS
  157.     /* CLOCK$ is also pointer, so need to map */
  158.     dd = map_real(doslist->clock, sizeof(DeviceDriver));
  159. #else
  160.     dd = doslist->clock;
  161. #endif
  162.     if (_fmemcmp(dd->u.name, "CLOCK$  ", 8) != 0)
  163.         fail("CLOCK$ name wrong");
  164.     if (! (dd->attr & IS_CLOCK))
  165.         fail("CLOCK$ attr wrong");
  166. #ifdef WINDOWS
  167.     free_mapped_seg(dd);
  168. #endif
  169.  
  170.     /* print out device chain */
  171.     dd = &doslist->nul;
  172. #ifdef WINDOWS
  173.     for (;;) 
  174.     { 
  175.         printf("%Fp    ", DosProtToReal(dd)); /* print real-mode addr */
  176.         if (dd->attr & CHAR_DEV)
  177.             printf("%.8Fs\r\n", dd->u.name);
  178.         else
  179.             printf("Block dev: %u unit(s)\r\n", dd->u.blk_cnt);
  180.         next = dd->next;            /* get next pointer */
  181.         /* first time through, this will free selector to doslist */
  182.         free_mapped_seg(dd);        /* THEN free rmode seg */
  183.         if (FP_OFF(next) == -1)     /* is there a next? */
  184.             break;
  185.         dd = map_real(next, sizeof(DeviceDriver));  /* map it */
  186.         Yield();    /* no message loop in this program, so yield */
  187.     }
  188. #else
  189.     do { 
  190.         printf("%Fp\t", dd);
  191.         if (dd->attr & CHAR_DEV)
  192.             printf("%.8Fs\n", dd->u.name); 
  193.         else
  194.             printf("Block dev: %u unit(s)\n", dd->u.blk_cnt);
  195.         dd = dd->next;
  196.     } while (FP_OFF(dd->next) != -1);
  197. #endif  
  198.     
  199. #ifdef WINDOWS  
  200.     if (mapped = get_mapped())
  201.         printf("%u remaining mapped selectors!\r\n", mapped);
  202.     show_display();
  203.     return mapped;  /* 0 indicates success */
  204. #else
  205.     return 0;
  206. #endif
  207. }
  208.